package com.blacktech.dbu.meta.service;

import com.blacktech.dbu.core.util.FieldTranslationUtil;
import com.blacktech.dbu.meta.dto.CreateFieldLibraryRequest;
import com.blacktech.dbu.meta.dto.FieldLibrarySearchRequest;
import com.blacktech.dbu.meta.dto.UpdateFieldLibraryRequest;
import com.blacktech.dbu.meta.entity.DbuFieldLibrary;
import com.blacktech.dbu.meta.repository.FieldLibraryRepository;
import com.blacktech.dbu.meta.repository.ProductRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

/**
 * 字段库服务类
 *
 * @author Yanyunsong
 */
@Slf4j
@Service
@Transactional
public class FieldLibraryService {

    @Autowired
    private FieldLibraryRepository fieldLibraryRepository;

    @Autowired
    private ProductRepository productRepository;

    @Autowired
    private FieldTranslationUtil translationUtil;

    /**
     * 创建字段库记录
     */
    public DbuFieldLibrary createField(CreateFieldLibraryRequest request) {
        log.info("创建字段库记录: productId={}, {}", request.getProductId(), request.getFieldNameCn());

        // 验证产品是否存在
        if (!productRepository.existsById(request.getProductId())) {
            throw new RuntimeException("产品不存在: " + request.getProductId());
        }

        // 检查英文名是否已存在（在同一产品内）
        String fieldNameEn = request.getFieldNameEn();
        if (fieldNameEn == null || fieldNameEn.trim().isEmpty()) {
            // 自动翻译中文名为英文
            fieldNameEn = translationUtil.translateToEnglish(request.getFieldNameCn());
        }

        fieldNameEn = translationUtil.normalizeFieldName(fieldNameEn);

        if (fieldLibraryRepository.existsByProductAndNameExcludeId(request.getProductId(), fieldNameEn, null)) {
            throw new RuntimeException("产品内字段英文名已存在: " + fieldNameEn);
        }

        DbuFieldLibrary field = new DbuFieldLibrary();
        BeanUtils.copyProperties(request, field);
        field.setFieldNameEn(fieldNameEn);
        field.setUsageCount(0);

        return fieldLibraryRepository.save(field);
    }

    /**
     * 更新字段库记录
     */
    public DbuFieldLibrary updateField(Long id, UpdateFieldLibraryRequest request) {
        log.info("更新字段库记录: {}", id);

        Optional<DbuFieldLibrary> optionalField = fieldLibraryRepository.findById(id);
        if (optionalField.isEmpty()) {
            throw new RuntimeException("字段库记录不存在: " + id);
        }

        DbuFieldLibrary field = optionalField.get();

        // 如果更新了英文名，检查是否重复
        if (request.getFieldNameEn() != null && !request.getFieldNameEn().equals(field.getFieldNameEn())) {
            String normalizedFieldNameEn = translationUtil.normalizeFieldName(request.getFieldNameEn());
            if (fieldLibraryRepository.existsByProductAndNameExcludeId(field.getProductId(), normalizedFieldNameEn, id)) {
                throw new RuntimeException("字段英文名已存在: " + normalizedFieldNameEn);
            }
            field.setFieldNameEn(normalizedFieldNameEn);
        }

        // 更新其他字段
        if (request.getFieldNameCn() != null) {
            field.setFieldNameCn(request.getFieldNameCn());
        }
        if (request.getFieldType() != null) {
            field.setFieldType(request.getFieldType());
        }
        if (request.getFieldLength() != null) {
            field.setFieldLength(request.getFieldLength());
        }
        if (request.getFieldScale() != null) {
            field.setFieldScale(request.getFieldScale());
        }
        if (request.getIsRequired() != null) {
            field.setIsRequired(request.getIsRequired());
        }
        if (request.getIsPrimaryKey() != null) {
            field.setIsPrimaryKey(request.getIsPrimaryKey());
        }
        if (request.getIsUnique() != null) {
            field.setIsUnique(request.getIsUnique());
        }
        if (request.getDefaultValue() != null) {
            field.setDefaultValue(request.getDefaultValue());
        }
        if (request.getFieldComment() != null) {
            field.setFieldComment(request.getFieldComment());
        }
        if (request.getIsEnabled() != null) {
            field.setIsEnabled(request.getIsEnabled());
        }

        return fieldLibraryRepository.save(field);
    }

    /**
     * 删除字段库记录
     */
    public void deleteField(Long id) {
        log.info("删除字段库记录: {}", id);

        if (!fieldLibraryRepository.existsById(id)) {
            throw new RuntimeException("字段库记录不存在: " + id);
        }

        fieldLibraryRepository.deleteById(id);
    }

    /**
     * 搜索字段库记录（按产品隔离）
     */
    @Transactional(readOnly = true)
    public Page<DbuFieldLibrary> searchFields(FieldLibrarySearchRequest request) {
        log.debug("搜索字段库记录: productId={}, {}", request.getProductId(), request.getKeyword());

        // 验证产品ID
        if (request.getProductId() == null) {
            throw new RuntimeException("产品ID不能为空");
        }

        Sort sort = Sort.by(
            "desc".equalsIgnoreCase(request.getSortDirection()) ?
                Sort.Direction.DESC : Sort.Direction.ASC,
            request.getSortBy()
        );

        Pageable pageable = PageRequest.of(request.getPage(), request.getSize(), sort);

        if (request.getKeyword() != null && !request.getKeyword().trim().isEmpty()) {
            return fieldLibraryRepository.searchByProduct(request.getProductId(), request.getKeyword().trim(), pageable);
        }

        // 如果没有关键词，使用其他条件筛选
        return fieldLibraryRepository.findAll((root, query, criteriaBuilder) -> {
            jakarta.persistence.criteria.Predicate predicate = criteriaBuilder.conjunction();

            // 产品ID筛选
            predicate = criteriaBuilder.and(predicate,
                criteriaBuilder.equal(root.get("productId"), request.getProductId()));

            if (request.getFieldType() != null) {
                predicate = criteriaBuilder.and(predicate,
                    criteriaBuilder.equal(root.get("fieldType"), request.getFieldType()));
            }

            if (request.getFieldGroup() != null && !request.getFieldGroup().trim().isEmpty()) {
                predicate = criteriaBuilder.and(predicate,
                    criteriaBuilder.equal(root.get("fieldGroup"), request.getFieldGroup()));
            }

            if (request.getIsRequired() != null) {
                predicate = criteriaBuilder.and(predicate,
                    criteriaBuilder.equal(root.get("isRequired"), request.getIsRequired()));
            }

            if (request.getIsPrimaryKey() != null) {
                predicate = criteriaBuilder.and(predicate,
                    criteriaBuilder.equal(root.get("isPrimaryKey"), request.getIsPrimaryKey()));
            }

            if (request.getIsUnique() != null) {
                predicate = criteriaBuilder.and(predicate,
                    criteriaBuilder.equal(root.get("isUnique"), request.getIsUnique()));
            }

            if (request.getIsEnabled() != null) {
                predicate = criteriaBuilder.and(predicate,
                    criteriaBuilder.equal(root.get("isEnabled"), request.getIsEnabled()));
            }

            return predicate;
        }, pageable);
    }


    /**
     * 获取指定产品的所有启用字段
     */
    @Transactional(readOnly = true)
    public List<DbuFieldLibrary> getAllFieldsByProduct(Long productId) {
        return fieldLibraryRepository.findByProduct(productId);
    }

    /**
     * 翻译中文名为英文
     */
    public String[] translateFieldName(String chineseName) {
        return translationUtil.getSuggestedNames(chineseName);
    }
}